var LinkItem = function(pcaption, paptype, plinkto, pdescription, psource)
{
	this.caption = pcaption;
	this.aptype = paptype;
	this.linkto = plinkto;
	this.description = pdescription;
	this.source = psource;
}

var LinkItems = function()
{
	this.items = new Array();
	this.items.length = 0;

	this.add = function(pobj)
	{
		this.items[this.items.length] = pobj;
		this.items.sort(function(a,b){if(b.caption>a.caption){return -1;}else{return 1;}});
	}

	this.search = function(psources, pkey)
	{
		var ret = new LinkItems();
		for(var icnt = 0; icnt < this.items.length; icnt++)
		{
			var mye = this.items[icnt];
			var bin = true;
			bin = bin && (new BasicUtil()).isinstrarray(psources, mye.source);
			if(pkey)
			{
				var keyl = pkey.split(" ");
				var blin = false;
				for(var kcnt = 0; kcnt < keyl.length; kcnt++)
				{
					var keye = keyl[kcnt];
					try
					{
						blin =  blin || (mye.caption.toUpperCase().indexOf(keye.toUpperCase()) != -1);
						blin =  blin || (mye.linkto.toUpperCase().indexOf(keye.toUpperCase()) != -1);
						blin =  blin || (mye.description.toUpperCase().indexOf(keye.toUpperCase()) != -1);
					}
					catch(err){}
					bin = bin && blin;
				}
			}

			if(bin)
			{
				ret.add(mye);
			}
		}
		return ret;
	}
}

var InheritUtil = function()
{
	this.doinherit = function(pinheriter, pinheritfrom)
	{
		var ret = pinheriter;
		for(var pn in pinheritfrom)
		{
			ret[pn] = pinheritfrom[pn];
		}
		return ret;
	}
}

var BasicUtil = function()
{
	this.randcolor = function()
	{
		var ret = "rgba(";
		for(var icnt = 0; icnt < 3; icnt++)
		{
			if(icnt != 0)
			{
				ret += ",";
			}
			var r = Math.floor(Math.random() * 255);
			ret += r.toString();
		}
		ret += ", 0.4)";
		return ret;
	}

	this.isinstrarray = function(parr, pstr)
	{
		var ret = false;
		for(var icnt = 0; icnt < parr.length; icnt++)
		{
			ret = ret || parr[icnt] == pstr;
		}
		return ret;
	}
}
var DOMUtil = function()
{
	this.createelement = function(ptag, pid)
	{
		var ret = document.createElement(ptag);
		if(pid)
		{
			ret.setAttribute("id", pid);
		}
		return ret;
	}
	this.createtable = function(pid)
	{
		return this.createelement("table", pid);
	}
	this.createrecord = function(pid)
	{
		return this.createelement("tr", pid);
	}
	this.createcolumn = function(pid)
	{
		return this.createelement("td", pid);
	}
	this.createinput = function(pid)
	{
		var ret = this.createelement("input", pid);
		ret.setAttribute("type", "text");
		return ret;
	}
	this.getelement = function(pid)
	{
		return document.getElementById(pid);
	}
	this.createbutton = function(pid)
	{
		var ret = this.createinput(pid);
		ret.setAttribute("type", "button");
		return ret;
	}
	this.creatediv = function(pid)
	{
		return this.createelement("div", pid);
	}
	this.createcanvas = function(pid)
	{
		return this.createelement("canvas", pid);
	}
	this.createiframe = function(pid)
	{
		return this.createelement("iframe", pid);
	}

	this.darkcurtainmessage = function(pmessage)
	{
		var canvasid = (new Date()).getTime().toString() + "darkcurtain";
		var myc = document.body.appendChild(this.createcanvas(canvasid));
		myc.style.position = "absolute";
		myc.style.zIndex = 100;
		myc.style.left = 0;
		myc.style.top = 0;
		myc.width = window.innerWidth;
		myc.height = window.innerHeight;
		myc.setAttribute("onclick", "var mya = document.getElementById('" + canvasid + "'); mya.parentNode.removeChild(mya);");
		var cx = myc.getContext("2d");
		cx.beginPath();
		cx.fillStyle = "rgba(0,0,0,0.7)";
		cx.fillRect(0, 0, myc.width, myc.height);
		cx.fillStyle = "white";
		cx.font = "20px 'MS UI Gothic'";
		var ml = pmessage.split("\n");
		for(var icnt = 0; icnt < ml.length; icnt++)
		{
			var mline = ml[icnt];
			cx.fillText(mline, 100, 300 + icnt * 30);
		}
		cx.closePath();
	}
}

var CanvasT = function(pid)
{
	(new InheritUtil()).doinherit(this, new BasicUtil());
	(new InheritUtil()).doinherit(this, new DOMUtil());

	document.body.setAttribute("oncontextmenu", "return false;");

	this.rootid = pid;
	this.rootnode = this.getelement(this.rootid);
	this.rows = this.rootnode.getAttribute("rows");
	this.cols = this.rootnode.getAttribute("cols");
	this.instancename = this.rootnode.getAttribute("instancename");
	this.buseaccess = false;
	try
	{
		this.buseaccess = (this.rootnode.getAttribute("useaccess").toUpperCase() == "TRUE");
	}catch(errr){}
	this.originalexcelfilename = this.rootnode.getAttribute("linklistexceloriginalfilename");
	this.originalaccessfilename = this.rootnode.getAttribute("linklistaccessoriginalfilename");
	this.nextid = 0;
	this.linklist = new LinkItems();
	this.currentlist = new LinkItems();

	var mysh = new ActiveXObject("WScript.Shell");
	var dpath = mysh.SpecialFolders("Desktop");
	this.desktopaccessfilename = (dpath + "\\LinkList.accdb");
	this.desktopexcelfilename = (dpath + "\\LinkList.xlsx");

	this.tablemode = false;
	this.descriptionareaid = "description_" + (new Date()).getTime().toString() + this.instancename;
	this.inlineframeid = "inlineframe_" + (new Date()).getTime().toString() + this.instancename;
	this.innertableareaid = "innertable_" + (new Date()).getTime().toString() + this.instancename;
	this.sourcefilesareaid = "sourcefiles_" + (new Date()).getTime().toString() + this.instancename;
	this.sourcetableareaid = "sourcetable_" + (new Date()).getTime().toString() + this.instancename;

	this.sourcecheckboxname = "sourcecheckbox_"  + (new Date()).getTime().toString() + this.instancename;

	this.searchkeyid = "searchkey" + (new Date()).getTime().toString() + this.instancename;
	this.searchbuttonid = "searchbutton" + (new Date()).getTime().toString() + this.instancename;

	this.sourcefiles = new Array();
	this.sourcefiles.length = 0;
	this.sourcefiles[this.sourcefiles.length] = "body";
	var sl = new Array();
	sl.length = 0;
	sl = sl.concat(document.getElementsByTagName("excelsource"));
	sl = sl.concat(document.getElementsByTagName("accesssource"));
	for(var icnt = 0; icnt < sl.length; icnt++)
	{
		try
		{
			this.sourcefiles[this.sourcefiles.length] = sl[icnt].getAttribute("filename");
		}catch(errr){}
	}
	this.sourcefiles[this.sourcefiles.length] = this.desktopaccessfilename;
	this.sourcefiles[this.sourcefiles.length] = this.desktopexcelfilename;

	this.initializeoriginalaccess = function()
	{
		var fu = new FileUtil();
		if(!fu.fileexists(this.originalaccessfilename))
		{
			(new AccessApp()).createdbfile(this.originalaccessfilename);
			var acc = new AccessClient(this.originalaccessfilename);
			acc.executenonquery("create table linklist (caption text(255), aptype text(255), linkto text(255), description text)");
			acc.executenonquery("insert into linklist (caption, aptype, linkto, description) values ('Google', 'explorer', 'http://www.google.com/', 'google')");
		}
	}

	this.initializeoriginalexcel = function()
	{
		var fu = new FileUtil();
		if(!fu.fileexists(this.originalexcelfilename))
		{
			var app = new ActiveXObject("Excel.Application");
			app.DisplayAlerts = false;
			var b = app.Workbooks.Add();
			var smax = b.Worksheets.Count;
			for(var scnt = 0; scnt < smax - 1; scnt++)
			{
				book.Worksheets.Item(smax - scnt).Delete();
			}
			var s = book.Worksheets.Item(1);
			s.Name = "LinkList";
			var ir = s.Range("A1");
			ir.Offset(0, 0).Value2 = "caption";
			ir.Offset(0, 1).Value2 = "aptype";
			ir.Offset(0, 2).Value2 = "linkto";
			ir.Offset(0, 3).Value2 = "description";
			ir.Offset(1, 0).Value2 = "google";
			ir.Offset(1, 1).Value2 = "explorer";
			ir.Offset(1, 2).Value2 = "http://www.google.com/";
			ir.Offset(1, 3).Value2 = "google";
			var xlWorkbookDefault = 51;
			b.SaveAs(this.originalexcelfilename, xlWorkbookDefault);
			b.Close();
			app.Quit();
		}
	}

	this.desktopextension = function()
	{
		var fu = new FileUtil();
		if(!fu.fileexists(this.desktopaccessfilename))
		{
			fu.copyfile(this.originalaccessfilename, this.desktopaccessfilename);
		}
		if(!fu.fileexists(this.desktopexcelfilename))
		{
			fu.copyfile(this.originalexcelfilename, this.desktopexcelfilename);
		}
	}

	this.copytolocal = function(pfn)
	{
		var fu = new FileUtil();
		var ext = "." + fu.fso.GetExtensionName(pfn);
		var destfn = fu.gettempfilename(ext);
		fu.copyfile(pfn, destfn);
		return destfn;
	}

	this.loadbodysources = function()
	{
		var pl = document.getElementsByTagName("listitem");
		for(var icnt = 0; icnt < pl.length; icnt++)
		{
			var pe = pl[icnt];
			this.linklist.add(new LinkItem(pe.getAttribute("caption"), pe.getAttribute("aptype"), pe.getAttribute("linkto"), pe.getAttribute("description"), "body"));
		}
		this.currentlist = this.linklist;
	}

	this.loadaccesssources = function()
	{
		var sl = document.getElementsByTagName("accesssource");
		var files = new Array();
		files[files.length] = this.desktopaccessfilename;
		for(var icnt = 0; icnt < sl.length; icnt++)
		{
			try
			{
				files[files.length] = sl[icnt].getAttribute("filename");
			}catch(err){}
		}
		for(var icnt = 0; icnt < files.length; icnt++)
		{
			var fn = files[icnt];
			var rl = (new AccessClient(this.copytolocal(fn))).executeselectquery("select * from linklist");
			for(var rcnt = 0; rcnt < rl.length; rcnt++)
			{
				var re = rl[rcnt];
				this.linklist.add(new LinkItem(re.caption, re.aptype, re.linkto, re.description, fn));
			}
		}
		this.currentlist = this.linklist;
	}

	this.loadexcelsources = function()
	{
		var el = document.getElementsByTagName("excelsource");
		var files = new Array();
		files[files.length] = this.desktopexcelfilename;
		if(el.length > 0)
		{
			for(var icnt = 0; icnt < el.length; icnt++)
			{
				files[files.length] = el[icnt].getAttribute("filename");
			}
		}
		var excelapp = new ActiveXObject("Excel.Application");
		excelapp.DisplayAlerts = false;
		for(var icnt = 0; icnt < files.length; icnt++)
		{
			var fn = files[icnt];
			var book = excelapp.Workbooks.Open(this.copytolocal(fn), null, true);
			var sheet = book.Worksheets.Item("LinkList");
			var ir = sheet.Range("A2");
			var roffset = 0;
			while(true)
			{
				var rowcell = ir.Offset(roffset, 0);
				if(rowcell.Text == "")
				{
					break;
				}
				else
				{
					this.linklist.add(new LinkItem(rowcell.Text, rowcell.Offset(0, 1).Text, rowcell.Offset(0, 2).Text, rowcell.Offset(0, 3).Text, fn));
				}
				roffset++;
			}
			book.Close();
		}
		excelapp.Quit();

		this.currentlist = this.linklist;
	}

	this.search = function()
	{
		this.currentlist = this.linklist.search(this.getcheckedsources(), this.getelement(this.searchkeyid).value);
		this.displayinnertable();
	}

	this.foldsourcefilter = function()
	{
		var mye = this.getelement(this.sourcefilesareaid);
		if(mye.style.display == "")
		{
			mye.style.display = "none";
		}
		else
		{
			mye.style.display = "";
		}
	}

	this.switchtable = function()
	{
		this.tablemode = !this.tablemode;
		this.displayinnertable();
	}

	this.display = function()
	{
		this.rootnode.innerHTML = "";
		var glt = this.rootnode.appendChild(this.createtable());
		var glr = glt.appendChild(this.createrecord());
		var gld = glr.appendChild(this.createcolumn());
		var stable = gld.appendChild(this.createtable());
		var sr = stable.appendChild(this.createrecord());
		var sd = sr.appendChild(this.createcolumn());
		var myi = sd.appendChild(this.createinput(this.searchkeyid));
		myi.setAttribute("accesskey", "s");
		myi.setAttribute("placeholder", "Alt + S to focus");
		sd = sr.appendChild(this.createcolumn());
		myi = sd.appendChild(this.createbutton(this.searchbuttonid));
		myi.setAttribute("value", "search");
		myi.setAttribute("onclick", this.instancename + ".search();");
		sd = sr.appendChild(this.createcolumn());
		sd.style.background = "#e6e6fa";
		sd.style.color = "blue";
		sd.setAttribute("onclick", this.instancename + ".foldsourcefilter();");
		sd.innerText = "source filter";

		sd = sr.appendChild(this.createcolumn());
		sd.style.background = "#e6e6fa";
		sd.style.color = "blue";
		sd.setAttribute("onclick", this.instancename + ".switchtable();");
		sd.innerText = "switch";

		sd = sr.appendChild(this.createcolumn());
		sd.style.background = "#e6e6fa";
		sd.style.color = "blue";
		sd.setAttribute("onclick", "window.close();");
		sd.innerText = "close";

		glr = glt.appendChild(this.createrecord(this.sourcefilesareaid));
		glr.style.display = "none";
		gld = glr.appendChild(this.createcolumn(this.sourcetableareaid));

		this.displaysourcetable();

		glr = glt.appendChild(this.createrecord());
		gld = glr.appendChild(this.createcolumn());
		gld.setAttribute("valign", "top");

		var gt = gld.appendChild(this.createtable());
		var gr = gt.appendChild(this.createrecord());
		var gd = gr.appendChild(this.createcolumn(this.innertableareaid));

		this.displayinnertable();

		gr = gt.appendChild(this.createrecord());
		gd = gr.appendChild(this.createcolumn());
		gd.setAttribute("align", "center");
		var canvasnext = gd.appendChild(this.createcanvas());
		canvasnext.width = Math.floor(canvasnext.width * this.cols);
		canvasnext.height = Math.floor(canvasnext.height / 2);
		canvasnext.setAttribute("onclick", this.instancename + ".displayinnertable();");
		var canvasnextcx = canvasnext.getContext("2d");
		canvasnextcx.beginPath();
		canvasnextcx.fillStyle = this.randcolor();
		canvasnextcx.fillRect(0, 0, canvasnext.width, canvasnext.height);
		canvasnextcx.fillStyle = "black";
		canvasnextcx.font = "20px 'MS UI Gothic'";
		canvasnextcx.textAlign = "center";
		canvasnextcx.fillText("Next", Math.floor(canvasnext.width / 2), Math.floor(canvasnext.height / 2));
		canvasnextcx.closePath();

		gld = glr.appendChild(this.createcolumn());
		gld.setAttribute("valign", "top");
		var descrarea = gld.appendChild(this.creatediv(this.descriptionareaid));
		descrarea.style.display = "none";
		descrarea.style.fontSize = "x-large";
		descrarea.style.color = "green";
		var ifr = gld.appendChild(this.createiframe(this.inlineframeid));
		ifr.style.display = "none";
		ifr.width = 1000;
		ifr.height = canvasnext.height * (this.rows * 2 + 1);
	}

	this.getcheckedsources = function()
	{
		var ret = new Array();
		ret.length = 0;
		var cl = document.getElementsByName(this.sourcecheckboxname);
		for(var icnt = 0; icnt < cl.length; icnt++)
		{
			var ce = cl[icnt];
			if(ce.checked)
			{
				ret[ret.length] = ce.value;
			}
		}
		return ret;
	}

	this.displaysourcetable = function()
	{
		var mya = this.getelement(this.sourcetableareaid);
		mya.innerHTML = "";
		var myt = mya.appendChild(this.createtable());
		for(var icnt = 0; icnt < this.sourcefiles.length; icnt++)
		{
			var se = this.sourcefiles[icnt];
			var r = myt.appendChild(this.createrecord());
			var d = r.appendChild(this.createcolumn());
			var c = d.appendChild(document.createElement("input"));
			c.setAttribute("type", "checkbox");
			c.setAttribute("name", this.sourcecheckboxname);
			c.setAttribute("value", se);
			c.setAttribute("checked", "checked");
			d = r.appendChild(this.createcolumn());
			if(se == "body")
			{
				d.innerText = se;
			}
			else
			{
				var myanc = d.appendChild(document.createElement("a"));
				myanc.setAttribute("href", (new FileUtil()).fso.GetFile(se).ParentFolder.Path);
				myanc.innerText = se;
			}
		}
	}

	this.displayinnertable = function()
	{
		var icounter = this.nextid;
		if(this.currentlist.items.length > 0)
		{
			var gd = this.getelement(this.innertableareaid);
			gd.innerHTML = "";
			var myt = gd.appendChild(this.createtable());
			if(this.tablemode)
			{
				for(var icnt = 0; icnt < this.currentlist.items.length; icnt++)
				{
					var le = this.currentlist.items[icnt];
					var r = myt.appendChild(this.createrecord());
					r.style.fontSize = "small";
					r.setAttribute("onclick", this.instancename + ".clicked(" + icnt.toString() + ");");
					if(icnt % 2 == 0)
					{
						r.style.backgroundColor = "#ffffe0";
					}
					var d = r.appendChild(this.createcolumn());
					d.innerText = le.caption;
					d = r.appendChild(this.createcolumn());
					try
					{
						d.innerHTML = (new StrUtil()).replaceall(le.description, "\n", "<br />");
					}
					catch(err)
					{
						d.innerText = le.description;
					}
					d = r.appendChild(this.createcolumn());
					d.innerText = le.aptype;
					d = r.appendChild(this.createcolumn());
					d.innerText = le.linkto;
				}
				icounter = 0;
			}
			else
			{
				for(var rcnt = 0; rcnt < this.rows; rcnt++)
				{
					var r = myt.appendChild(this.createrecord());
					for(var ccnt = 0; ccnt < this.cols; ccnt++)
					{
						var ce = this.currentlist.items[icounter];
						var d = r.appendChild(this.createcolumn());
						var abbr = d.appendChild(document.createElement("abbr"));
						try
						{
							var abbrstr = ce.description + "\n" + ce.linkto;
							abbr.setAttribute("title", abbrstr);
						}catch(err){}
						var c = abbr.appendChild(this.createcanvas());
						c.setAttribute("onclick", this.instancename + ".clicked(" + icounter.toString() + ");");
						c.setAttribute("oncontextmenu", this.instancename + ".rightclicked(" + icounter.toString() + ");");
						var cx = c.getContext("2d");
						cx.beginPath();
						cx.fillStyle = this.randcolor();
						cx.fillRect(0, 0, c.width, c.height);
						cx.fillStyle = "black";
						cx.textAlign = "center";
						cx.font = "20px 'MS UI Gothic'";
						cx.fillText(ce.caption, Math.floor(c.width / 2), Math.floor(c.height / 2));
						cx.closePath();

						icounter++;
						if(icounter >= this.currentlist.items.length)
						{
							icounter = 0;
						}
					}
				}
			}
			this.nextid = icounter;
		}
	}

	this.clicked = function(pidx)
	{
		var myi = this.currentlist.items[pidx];
		switch(myi.aptype.toUpperCase())
		{
			case "INLINEFRAME":
				{
					this.getelement(this.inlineframeid).setAttribute("src", myi.linkto);
					this.getelement(this.inlineframeid).style.display = "";
					break;
				}
			case "EXPLORER":
				{
					(new ShellUtil()).run(myi.linkto);
					break;
				}
			default:
				{
					break;
				}
		}
	}

	this.rightclicked = function(pidx)
	{
		var myi = this.currentlist.items[pidx];
		this.darkcurtainmessage(myi.caption + "\n" + myi.linkto + "\n" + myi.description);
	}

	this.initializeoriginalaccess();
	this.initializeoriginalexcel();
	this.desktopextension();
	this.loadbodysources();
	this.loadaccesssources();
	this.loadexcelsources();
}
